package com.ziytek.web.citizen.service.impl;

import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.event.VersionEvent;
import com.ziytek.web.citizen.model.bean.BatteriesDetails;
import com.ziytek.web.citizen.model.bean.DetailsData;
import com.ziytek.web.citizen.model.bean.OneDetails;
import com.ziytek.web.citizen.model.bean.OneDetailsInfo;
import com.ziytek.web.citizen.service.itf.BatteriesDetailsService;
import com.ziytek.web.citizen.util.CabinetNoUtil;
import com.ziytek.web.citizen.util.HexUtil;
import com.ziytek.web.citizen.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @author fenghx
 * @version 1.0
 * @className BatteriesDetailsServiceImpl
 * Description: 电池详情数据解析
 * @date 2024/3/27 14:02
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BatteriesDetailsServiceImpl implements BatteriesDetailsService {
    private final ApplicationContext context;
    private final BatteryDataProcessorServiceImpl batteryDataProcessorService;

    @Override
    public CompletableFuture<List<BatteriesDetails>> getOneBatteriesDetails(String originalData, String lineCode, Long time) {
        if (StringUtil.isEmpty(originalData) || originalData.length() != NumConstant.INT_DATA_ACTUAL_LENGTH) {
            log.error("getOneBatteriesDetails电芯周期数据处理失败，数据长度不对length[{}]", originalData.length());
            return CompletableFuture.completedFuture(null);
        }

        var by = lineCode.split(ServerConstant.DATA_SEPARATOR_SPACE);
        if (by.length != NumConstant.INT_TWO) {
            return CompletableFuture.completedFuture(null);
        }

        var controlAddress = by[NumConstant.INT_ZERO];
        var position = by[NumConstant.INT_ONE];
        var bordData = originalData.substring(NumConstant.INT_TEN, NumConstant.INT_END);
        String batteryData = null;

        for (int i = NumConstant.INT_ZERO; i < bordData.length() / ServerConstant.BATTERIES_DATA_LENGTH; i++) {
            String bData = bordData.substring(i * ServerConstant.BATTERIES_DATA_LENGTH, (i + NumConstant.INT_ONE) * ServerConstant.BATTERIES_DATA_LENGTH);
            if (bData.substring(ServerConstant.DATA_TYPE_LEN_0, ServerConstant.DATA_TYPE_LEN_1).equals(controlAddress)) {
                batteryData = bData;
                break;
            }
        }

        if (batteryData == null || batteryData.length() != NumConstant.INT_EIGHTY_FOUR) {
            return CompletableFuture.completedFuture(null);
        }

        batteryData = batteryData.substring(NumConstant.INT_FOUR, NumConstant.INT_EIGHTY_FOUR);

        List<BatteriesDetails> batteryInfoList = new ArrayList<>();
        for (int i = NumConstant.INT_ZERO; i < batteryData.length() / ServerConstant.BATTERIES_ONE_DATA_LENGTH; i++) {
            var bData = batteryData.substring(i * ServerConstant.BATTERIES_ONE_DATA_LENGTH, (i + NumConstant.INT_ONE) * ServerConstant.BATTERIES_ONE_DATA_LENGTH);
            var batteryNum = StringUtil.toInt(bData.substring(ServerConstant.DATA_TYPE_LEN_0, ServerConstant.DATA_TYPE_LEN_1)) + "";
            if (batteryNum.equals(position)) {
                var electricity = bData.substring(ServerConstant.DATA_TYPE_LEN_1, ServerConstant.DATA_TYPE_LEN_END);
                var voltage = bData.substring(ServerConstant.DATA_TYPE_LEN_END, ServerConstant.BATTERIES_ONE_DATA_LENGTH);

                var electricityNum = HexUtil.hexToInt(electricity);
                // 电流数据小于5的,视为0
                electricityNum = electricityNum <= NumConstant.CACHE_FLEX_TIME ? ServerConstant.DATA_TYPE_LEN_0 : electricityNum;
                var voltageNum = HexUtil.hexToInt(voltage);

                var details = new BatteriesDetails();
                //details.setCt(time == null ? System.currentTimeMillis() : time);
                details.setC(StringUtil.toFloat(String.valueOf(electricityNum)));
                details.setV(StringUtil.toFloat(String.valueOf(voltageNum)));
                batteryInfoList.add(details);
                break;
            }
        }

        return CompletableFuture.completedFuture(batteryInfoList);
    }

    @Override
    public CompletableFuture<DetailsData> getBatteriesDetails(String originalData, String lineCode, String key, Long time) {
        if (StringUtil.isEmpty(originalData) || originalData.length() != NumConstant.INT_DATA_ACTUAL_LENGTH) {
            if (StringUtil.isNotEmpty(originalData) && originalData.length() > NumConstant.INT_ONE_HUNDRED) {
                log.error("getBatteriesDetails电芯周期数据处理失败，数据长度不对length[{}]", originalData.length());
            }
            return CompletableFuture.completedFuture(null);
        }

        var split = lineCode.split(ServerConstant.DATA_SEPARATOR_SPACE);
        if (split.length != NumConstant.INT_TWO) {
            return CompletableFuture.completedFuture(null);
        }

        String batteryData = null;
        var position = split[NumConstant.INT_ONE];
        var controlAddress = split[NumConstant.INT_ZERO];
        var bordData = originalData.substring(NumConstant.INT_TEN, NumConstant.INT_END);

        for (int i = NumConstant.INT_ZERO; i < bordData.length() / ServerConstant.BATTERIES_DATA_LENGTH; i++) {
            var bData = bordData.substring(i * ServerConstant.BATTERIES_DATA_LENGTH, (i + NumConstant.INT_ONE) * ServerConstant.BATTERIES_DATA_LENGTH);
            if (bData.substring(ServerConstant.DATA_TYPE_LEN_0, ServerConstant.DATA_TYPE_LEN_1).equals(controlAddress)) {
                batteryData = bData;
                break;
            }
        }

        if (batteryData == null || batteryData.length() != NumConstant.INT_EIGHTY_FOUR) {
            return CompletableFuture.completedFuture(null);
        }

        batteryData = batteryData.substring(NumConstant.INT_FOUR, NumConstant.INT_EIGHTY_FOUR);
        for (int i = NumConstant.INT_ZERO; i < batteryData.length() / ServerConstant.BATTERIES_ONE_DATA_LENGTH; i++) {
            var bData = batteryData.substring(i * ServerConstant.BATTERIES_ONE_DATA_LENGTH, (i + NumConstant.INT_ONE) * ServerConstant.BATTERIES_ONE_DATA_LENGTH);
            var batteryNum = StringUtil.toInt(bData.substring(ServerConstant.DATA_TYPE_LEN_0, ServerConstant.DATA_TYPE_LEN_1)) + "";
            if (batteryNum.equals(position)) {
                var electricity = bData.substring(ServerConstant.DATA_TYPE_LEN_1, ServerConstant.DATA_TYPE_LEN_END);
                var voltage = bData.substring(ServerConstant.DATA_TYPE_LEN_END, ServerConstant.BATTERIES_ONE_DATA_LENGTH);

                var electricityNum = HexUtil.hexToInt(electricity);
                // 电流数据小于5的,视为0
                electricityNum = electricityNum <= NumConstant.CACHE_FLEX_TIME ? ServerConstant.DATA_TYPE_LEN_0 : electricityNum;
                var voltageNum = HexUtil.hexToInt(voltage);

                var details = DetailsData.builder()
                        .k(key)
                        .v(StringUtil.toFloat(String.valueOf(voltageNum)))
                        .t(time == null ? System.currentTimeMillis() : time)
                        .c(StringUtil.toFloat(String.valueOf(electricityNum)))
                        .build();
                return CompletableFuture.completedFuture(details);
            }
        }

        return CompletableFuture.completedFuture(null);
    }

    @Override
    public Map<String, OneDetails> getAllBatteriesDetails(String originalData, String cabinetCode) {
        if (StringUtil.isEmpty(originalData) || originalData.length() != NumConstant.INT_DATA_ACTUAL_LENGTH) {
            if (StringUtil.isNotEmpty(originalData) && originalData.length() > NumConstant.INT_ONE_HUNDRED) {
                log.error("getAllBatteriesDetails，数据长度不对length[{}]", originalData.length());
            }
            return Collections.emptyMap();
        }

        // 实际有效数据
        var realData = originalData.substring(NumConstant.INT_TWELVE, NumConstant.INT_DATA_END);
        List<OneDetailsInfo> allBatteriesDetails = batteryDataProcessorService.processAllBatteriesDetails(realData, cabinetCode, false);
        if (CollectionUtils.isEmpty(allBatteriesDetails)) {
            return Collections.emptyMap();
        }

        Map<String, OneDetails> allMap = new HashMap<>();
        Map<String, String> versionMap = new HashMap<>();
        // 使用Java 8的流来优化性能和代码可读性
        allBatteriesDetails.stream()
                .filter(oneDetailsInfo -> oneDetailsInfo != null && !CollectionUtils.isEmpty(oneDetailsInfo.getOneDetailsMap()))
                .map(OneDetailsInfo::getOneDetailsMap)
                .forEach(allMap::putAll);

        // 使用Java 8的流来优化性能和代码可读性
        allBatteriesDetails.stream()
                .filter(versionInfo -> versionInfo != null && !CollectionUtils.isEmpty(versionInfo.getControlVersionMap()))
                .map(OneDetailsInfo::getControlVersionMap)
                .forEach(versionMap::putAll);

        // 发布分控版本信息事件
        context.publishEvent(new VersionEvent(CabinetNoUtil.getCabinetNo(cabinetCode), versionMap));
        //log.info("allMap size[{}]", allMap.size());
        return allMap;
    }

    @Override
    public Map<String, Float> getAllCapacityDetails(String originalData, String cabinetCode) {
        if (StringUtil.isEmpty(originalData) || originalData.length() != NumConstant.INT_DATA_ACTUAL_LENGTH) {
            if (StringUtil.isNotEmpty(originalData) && originalData.length() > NumConstant.INT_ONE_HUNDRED) {
                log.error("getAllCapacityDetails，数据长度不对length[{}]", originalData.length());
            }
            return Collections.emptyMap();
        }

        // 实际有效数据
        String realData = originalData.substring(NumConstant.INT_TWELVE, NumConstant.INT_DATA_END);
        List<OneDetailsInfo> allBatteriesDetails = batteryDataProcessorService.processAllBatteriesDetails(realData, cabinetCode, true);
        if (CollectionUtils.isEmpty(allBatteriesDetails)) {
            return Collections.emptyMap();
        }

        Map<String, Float> capacityMap = new HashMap<>();
        // 使用Java 8的流来优化性能和代码可读性
        allBatteriesDetails.stream()
                .filter(oneDetailsInfo -> oneDetailsInfo != null && !CollectionUtils.isEmpty(oneDetailsInfo.getCapacityMap()))
                .map(OneDetailsInfo::getCapacityMap)
                .forEach(capacityMap::putAll);

        return capacityMap;
    }
}
